package com.molihub.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.molihub.entity.*;
import com.molihub.listener.ApplicationStartListener;
import com.molihub.utils.AddressUtils;
import com.molihub.utils.LogUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassName: SystemController
 * @Description: 系统跳转控制器
 * @author: xw
 * @date 2020/2/1 15:04
 * @Version: 1.0
 **/
@Controller
public class SystemController extends BaseController {

    Logger logger = LogUtils.getInstance(SystemController.class);

    /**
     * @return java.lang.String
     * @Description 前往发布文章页面
     * @Author xw
     * @Date 23:25 2020/1/31
     * @Param [map]
     **/
    @GetMapping("/publish-article")
    public String toPublishPage(Map<String, Object> map) {
        List<ArticleKind> kinds = articleKindService.getArticleKindsByUserId(loginUser.getUserId());
        map.put("kinds", kinds);
        logger.info("发布文章页面域中的数据:" + map);
        return "u-admin/new-article";
    }


    /**
     * @return java.lang.String
     * @Description 前往用户后台主页
     * @Author xw
     * @Date 14:34 2020/2/6
     * @Param [map]
     **/
    @GetMapping("/user-admin")
    public String toUadminPage(Map<String, Object> map) {
        //获取最新发表的前5篇文章
        Page<Object> page = PageHelper.startPage(1, 5);
        List<Article> articles = articleService.getArticlesByUserId(loginUser.getUserId());
        for (Article article : articles) {
            article.setArticleContent("");
        }
        //获取最新的3条未读消息
        List<Message> messages = messageService.getAllMessageWithCondition(loginUser.getUserId(), false);
        int count = messages.size();
        messages = messages.stream().limit(3).collect(Collectors.toList());
        List<MessageToShow> messageToShows = transformMessage(messages, loginUser);
        //获取访问量与阅读量（近七天）
        //获取近七天的个人空间访问量
        List<VisitorStatistic> statisticV = visitorService.getStatisticIn7Days(loginUser.getUserId(), 0);
        List<VisitorStatistic> statisticR = visitorService.getStatisticIn7Days(loginUser.getUserId(), 1);
        //获得今日用户访客各个省份的访问数据
        List<RegionStatistic> regionStatistics = visitorService.getTodayVisitors(loginUser.getUserId());
        Map<String, Map<String, String>> regions = new HashMap<>();
        int sum = 0;
        for (RegionStatistic statistic : regionStatistics) {
            sum += statistic.getCount();
        }
        for (RegionStatistic region : regionStatistics) {
            Map<String, String> temp = new HashMap<>();
            Double value = new BigDecimal((float) region.getCount() / sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            Integer color = value >= 0.3 ? 0 : value >= 0.2 ? 1 : value >= 0.1 ? 2 : 7;
            temp.put("value", value * 100 + "%");
            temp.put("stateInitColor", color.toString());
            temp.put("sum", Integer.toString(region.getCount()));
            regions.put(region.getRegion(), temp);
        }
        //获得作者文章总共发表的个数
        ArticleCountStatistics statistics = articleService.statistics(loginUser.getUserId());
        map.put("articles", articles);
        map.put("newMessageCount", count);
        map.put("messages", messageToShows);
        map.put("publishedCount", statistics.getPublished());
        map.put("regions", JSONObject.toJSONString(regions));
        map.put("statisticV", JSONObject.toJSONString(statisticV));
        map.put("statisticR", JSONObject.toJSONString(statisticR));
        logger.info("用户后台主页域中的数据:" + map);
        return "u-admin/index";
    }

    /**
     * @return java.lang.String
     * @Description 前往我的所有发布文章页面
     * @Author xw
     * @Date 23:25 2020/1/31
     * @Param [map]
     **/
    @GetMapping("/all-published-articles")
    public String toMyPublishedArticlePage(Integer current, Map<String, Object> map) {
        Integer pageSize = 10;
        //判断current参数是否为空，为空则默认当前页为1
        int cur = current == null ? 1 : current;
        ArticleCountStatistics statistics = articleService.statistics(loginUser.getUserId());
        int maxPage = statistics.getTotal() % pageSize == 0 ? (statistics.getTotal() / pageSize) : (statistics.getTotal() / pageSize) + 1;
        //如果当前页大于最页，给当前页赋值为最大页。如果当前页小于等于0，那么赋值为第1页
        cur = cur >= maxPage ? maxPage : cur <= 0 ? 1 : cur;
        Page<Object> page = PageHelper.startPage(cur, pageSize);
        List<Article> articles = articleService.getArticlesByUserIdAndStatus(loginUser.getUserId(), 0);
        List<ArticleToShow> articleToShows = transformArticle(articles, loginUser);
        map.put("statistics", statistics);
        map.put("page", page);
        map.put("articles", articleToShows);
        logger.info("已发布文章页面域中的数据:" + map);
        return "u-admin/published-articles";
    }

    /**
     * @return java.lang.String
     * @Description 前往我的所有草稿文章页面
     * @Author xw
     * @Date 23:25 2020/1/31
     * @Param [map]
     **/
    @GetMapping("/all-draft-articles")
    public String toMyDraftArticlePage(Integer current, Map<String, Object> map) {
        Integer pageSize = 10;
        //判断current参数是否为空，为空则默认当前页为1
        int cur = current == null ? 1 : current;
        ArticleCountStatistics statistics = articleService.statistics(loginUser.getUserId());
        int maxPage = statistics.getTotal() % pageSize == 0 ? (statistics.getTotal() / pageSize) : (statistics.getTotal() / pageSize) + 1;
        //如果当前页大于最页，给当前页赋值为最大页。如果当前页小于等于0，那么赋值为第1页
        cur = cur >= maxPage ? maxPage : cur <= 0 ? 1 : cur;
        Page<Object> page = PageHelper.startPage(cur, pageSize);
        List<Article> articles = articleService.getArticlesByUserIdAndStatus(loginUser.getUserId(), 1);
        List<ArticleToShow> articleToShows = transformArticle(articles, loginUser);
        map.put("statistics", statistics);
        map.put("page", page);
        map.put("articles", articleToShows);
        logger.info("草稿文章页面域中的数据:" + map);
        return "u-admin/draft-articles";
    }

    /**
     * @return java.lang.String
     * @Description 前往我的所有回收站文章页面
     * @Author xw
     * @Date 23:25 2020/1/31
     * @Param [map]
     **/
    @GetMapping("/all-trash-articles")
    public String toMyTrashArticlePage(Integer current, Map<String, Object> map) {
        Integer pageSize = 10;
        //判断current参数是否为空，为空则默认当前页为1
        int cur = current == null ? 1 : current;
        ArticleCountStatistics statistics = articleService.statistics(loginUser.getUserId());
        int maxPage = statistics.getTotal() % pageSize == 0 ? (statistics.getTotal() / pageSize) : (statistics.getTotal() / pageSize) + 1;
        //如果当前页大于最页，给当前页赋值为最大页。如果当前页小于等于0，那么赋值为第1页
        cur = cur >= maxPage ? maxPage : cur <= 0 ? 1 : cur;
        Page<Object> page = PageHelper.startPage(cur, pageSize);
        List<Article> articles = articleService.getArticlesByUserIdAndStatus(loginUser.getUserId(), 2);
        List<ArticleToShow> articleToShows = transformArticle(articles, loginUser);
        map.put("statistics", statistics);
        map.put("page", page);
        map.put("articles", articleToShows);
        logger.info("垃圾箱文章页面域中的数据:" + map);
        return "u-admin/trash-articles";
    }

    @GetMapping("/article-kinds-tags")
    public String toArticleKindsPage(String which, Integer current, Map<String, Object> map) {
        int curKind = 1, curTag = 1, pageSize = 10;
        //获得用户的文章分类数和标签数
        Integer kindCount = articleKindService.getKindCountByUserId(loginUser.getUserId());
        Integer tagCount = articleTagService.getTagCountByUserId(loginUser.getUserId());
        if (current != null) {
            if ("kind".equals(which)) {
                curKind = current == null ? 1 : current;
                int maxPage = kindCount % pageSize == 0 ? (kindCount / pageSize) : (kindCount / pageSize) + 1;
                curKind = curKind >= maxPage ? maxPage : curKind <= 0 ? 1 : curKind;
            } else if ("tag".equals(which)) {
                curTag = current == null ? 1 : current;
                int maxPage = tagCount % pageSize == 0 ? (tagCount / pageSize) : (tagCount / pageSize) + 1;
                curTag = curTag >= maxPage ? maxPage : curTag <= 0 ? 1 : curTag;
            }
        }
        Page<Object> pageKind = PageHelper.startPage(curKind, pageSize);
        List<ArticleKind> kindsByUserId = articleKindService.getArticleKindsByUserId(loginUser.getUserId());
        List<ArticleKindToShow> kindToShows = transformKind(kindsByUserId, loginUser);
        Page<Object> pageTag = PageHelper.startPage(curTag, pageSize);
        List<ArticleTag> tagsByUserId = articleTagService.getArticleTagsByUserId(loginUser.getUserId());
        List<ArticleTagToShow> tagToShows = transformTag(tagsByUserId, loginUser);
        map.put("kinds", kindToShows);
        map.put("tags", tagToShows);
        map.put("kindCount", kindCount);
        map.put("tagCount", tagCount);
        map.put("pageKind", pageKind);
        map.put("pageTag", pageTag);
        logger.info("编辑分类目录和标签页面域中的数据:" + map);
        return "u-admin/kinds-and-tags";
    }

    @GetMapping("/edit-article")
    public String toEditArticlePage(Integer articleId, Map<String, Object> map) {
        if (articleId == null) {
            logger.error("携带必须参数为空,跳转到已发布文章列表页面!");
            return "redirect:/publish-article";
        }
        List<ArticleKind> kinds = articleKindService.getArticleKindsByUserId(loginUser.getUserId());
        map.put("kinds", kinds);
        Article article = articleService.getArticleById(articleId);
        map.put("kinds", kinds);
        map.put("article", article);
        logger.info("编辑文章页面域中的数据:" + map);
        return "u-admin/edit-article";
    }

    /**
     * 跳转到个人主页
     *
     * @return java.lang.String
     * @author GGBOY, xw
     * @date 2020/2/8
     */
    @GetMapping("/ProfilePage")
    public String toProfilePage(Map<String, Object> map) {
        if (loginUser == null) {
            // 代表未登录，不能访问个人主页
            return "redirect:/login.html";
        } else {
            //添加访问量
            String ip = getIpAddress(request);
            Visitor visitor = AddressUtils.getVisitor(ip);
            if (visitor != null) {
                visitor.setType(0);
                visitor.setVisitorId(loginUser.getUserId());
                visitor.setUserId(loginUser.getUserId());
                visitorService.insert(visitor);
            }
            //获得5篇阅读量最高文章
            PageHelper.startPage(0, 5);
            List<Article> famousArticles = articleService.getFamousArticles(loginUser.getUserId());
            //获得自己的分类目录和对应的文章数量
            List<ArticleKind> kindsByUserId = articleKindService.getArticleKindsByUserId(loginUser.getUserId());
            List<ArticleKindToShow> kindToShows = transformKind(kindsByUserId, loginUser);
            //获得自己的标签和对应的文章数量
            List<ArticleTag> tagsByUserId = articleTagService.getArticleTagsByUserId(loginUser.getUserId());
            List<ArticleTagToShow> tagToShows = transformTag(tagsByUserId, loginUser);
            //获得文章的日期归档信息
            List<ArticleDateArchive> archives = articleService.getArchive(loginUser.getUserId());
            HomePage myHomePage = homePageService.findPageById(loginUser.getUserId());
            // 获得5篇我曾经发布的文章
            PageHelper.startPage(0, 5);
            List<Article> articles = articleService.getAllArticlesByUserId(loginUser.getUserId());
            List<ArticleToShow> articleToShows = new ArrayList<>(10);
            // 封装文章信息
            traversalArticleList(articleToShows, articles);
            logger.info("ProfilePage: articles size: " + articleToShows.size());
            List<List<String>> images = new ArrayList<>();
            for (Article article : articles) {
                if (article.getImgPath() != null) {
                    List<String> strings = new ArrayList<>();
                    JSONArray jsonArray = JSONArray.parseArray(article.getImgPath());
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        String path = (String) jsonObject.get("path");
                        strings.add(path);
                    }
                    images.add(strings);
                } else {
                    images.add(null);
                }
            }
            // 遍历每篇文章，看看我是否点过赞
            List<Boolean> booleanList = new ArrayList<>();
            for (ArticleToShow articleToShow : articleToShows) {
                int i;
                for(i = 0; i < articleToShow.getLikeUserList().size(); i++){
                    if(articleToShow.getLikeUserList().get(i).getUserName().equals(loginUser.getUserName())){
                        booleanList.add(true);
                        break;
                    }
                }
                if(i == articleToShow.getLikeUserList().size()){
                    booleanList.add(false);
                }
            }
            map.put("whetherLike", booleanList);
            map.put("articles", articleToShows);
            map.put("images", images);
            map.put("visitUser", loginUser);
            map.put("famousArticles", famousArticles);
            map.put("archives", archives);
            map.put("kindToShows", kindToShows);
            map.put("tagToShows", tagToShows);
            session.setAttribute("homePage", myHomePage);
            return "ProfilePage";
        }
    }

    /**
     * 跳转到个人主页的朋友页面
     *
     * @return java.lang.String
     * @author GGBOY
     * @date 2020/2/8
     */
    @GetMapping("/profileFriends")
    public String toProfilePageWithFriends() {
        if (loginUser == null) {
            // 代表未登录，不能访问个人主页
            return "redirect:/login.html";
        } else {
            // 获得个人主页
            HomePage myHomePage = homePageService.findPageById(loginUser.getUserId());
            session.setAttribute("homePage", myHomePage);
            // 获取好友列表
            List<User> friends = friendService.findAllFriendById(loginUser.getUserId());
            // 获得好友数量
            int friendsNumber = friends.size();
            logger.info("用户:" + loginUser.getUserName() + "的朋友数量：" + friendsNumber);
            request.setAttribute("friendsNumber", friendsNumber);
            // 获得好友关系记录实体类
            List<Friend> friendList = friendService.findAllRecordById(loginUser.getUserId());
            logger.info("friendList的长度为：" + friendList.size());
            // 封装到对应的页面显示的实体类中
            List<ProfilePageFriend> profilePageFriendList = new ArrayList<>();
            for (int i = 0; i < friendsNumber; i++) {
                ProfilePageFriend profilePageFriend = new ProfilePageFriend();
                profilePageFriend.setUser(friends.get(i));
                profilePageFriend.setFriend(friendList.get(i));
                // 获得好友的个人主页
                HomePage homePage = homePageService.findPageById(friends.get(i).getUserId());
                profilePageFriend.setHomePage(homePage);
                profilePageFriendList.add(profilePageFriend);
            }
            request.setAttribute("friends", profilePageFriendList);
            return "ProfilePageWithFriends";
        }
    }

    /**
     * @return java.lang.String
     * @Description 阅读文章
     * @Author xw
     * @Date 23:28 2020/2/10
     * @Param [uId, uName, aId, title, map]
     **/
    @GetMapping("/read-article")
    public String toReadArticlePage(Integer uId, String uName, Integer aId, String title
            , Map<String, Object> map) {
        logger.info("toReadArticlePage---------------------------------->");
        Article article = articleService.getArticleById(aId);
        if (article == null) {
            return "error/4xx";
        } else if (article.isSecret() == true && loginUser.getUserId() != uId) {
            logger.error("没有权限阅读该文章! id=" + aId);
            return "error/4xx";
        } else {
            String ip = getIpAddress(request);
            Visitor visitor = AddressUtils.getVisitor(ip);
            if (visitor != null) {
                visitor.setArticleId(aId);
                visitor.setType(1);
                visitor.setVisitorId(loginUser.getUserId());
                visitor.setUserId(uId);
                //增加阅读量
                visitorService.insert(visitor);
                visitor.setType(0);
                visitor.setArticleId(null);
                //增加访问量
                visitorService.insert(visitor);
            }
            //查找用户最新5篇公开发布状态的文章
            Article search = Article.builder().userId(uId).secret(false).type(1).build();
            PageHelper.startPage(1, 5);
            List<Article> list = articleService.searchArticles(search);
            for (Article a : list) {
                a.setArticleContent("");
            }
            map.put("shows", list);
            //查找5篇含有共同标签的阅读量高的文章
            String[] tags = article.getArticleTags().split(",");
            //处理得到的流，去重、根据阅读量排序、截取最新的5篇
            List<Article> interest = getArticlesByTags(tags, (str) -> {
                PageHelper.startPage(1, 3);
                return articleService.getArticlesByUserAndTag(uId, str, 0, false, aId);
            }).stream().distinct()
                    .sorted((x, y) -> y.getReadCount().compareTo(x.getReadCount()))
                    .limit(5).collect(Collectors.toList());
            map.put("interest", interest);
            //增加阅读量
            articleService.addReadCount(aId);
            article.setReadCount(article.getReadCount() + 1);

            // 获得该文章对应的所有评论
            List<ArticleCommentToShow> articleComments = articleCommentService.getCommentsByArticleId(article.getArticleId());
            // 抽取评论中的所有一级评论
            List<ArticleCommentToShow> oneLevelComment = extractFatherComment(articleComments);
            // 将所有二级评论添加到对应的一级评论中
            extractChildCommentToFatherComment(articleComments, oneLevelComment);
            ArticleToShow articleToShow = ArticleToShow.builder().article(article).likeCount(10).commentCount(50)
                    .articleComments(oneLevelComment).build();
            articleToShow.setAuthor(userService.getUserByUserName(uName));
            if ("".equals(title) || title == null) {
                List<String> images = new ArrayList<>();
                if (article.getImgPath() != null) {
                    JSONArray jsonArray = JSONArray.parseArray(article.getImgPath());
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                        String path = (String) jsonObject.get("path");
                        images.add(path);
                    }
                }
                map.put("images", images);
            }
            map.put("article", articleToShow);

        }
        logger.info("阅读文章页面域中的数据:" + map);
        return "read-article";
    }

    /**
     * @return java.lang.String
     * @Description 前往我的网盘
     * @Author xw
     * @Date 23:28 2020/2/10
     * @Param [fId, fName, error, map]
     **/
    @GetMapping("/file-store")
    public String toFileStorePage(Integer fId, String fName, Integer error, Map<String, Object> map) {
        //获得统计信息
        FileStoreStatistics statistics = myFileService.getCountStatistics(loginUser.getFileStoreId());
        statistics.setFileStore(fileStoreService.getFileStoreById(loginUser.getFileStoreId()));
        //判断是否包含错误信息
        if (error != null) {
            if (error == 1) {
                map.put("error", "添加失败！当前已存在同名文件夹");
            }
            if (error == 2) {
                map.put("error", "重命名失败！文件夹已存在");
            }
        }
        //包含的子文件夹
        List<FileFolder> folders = null;
        //包含的文件
        List<MyFile> files = null;
        //当前文件夹信息
        FileFolder nowFolder = null;
        //当前文件夹的相对路径
        List<FileFolder> location = new ArrayList<>();
        if (fId == null || fId <= 0) {
            //代表当前为根目录
            fId = 0;
            folders = fileFolderService.getRootFoldersByFileStoreId(loginUser.getFileStoreId());
            files = myFileService.getRootFilesByFileStoreId(loginUser.getFileStoreId());
            nowFolder = FileFolder.builder().fileFolderId(fId).build();
            location.add(nowFolder);
        } else {
            //当前为具体目录
            folders = fileFolderService.getFileFolderByParentFolderId(fId);
            files = myFileService.getFilesByParentFolderId(fId);
            nowFolder = fileFolderService.getFileFolderByFileFolderId(fId);
            //遍历查询当前目录
            FileFolder temp = nowFolder;
            while (temp.getParentFolderId() != 0) {
                temp = fileFolderService.getFileFolderByFileFolderId(temp.getParentFolderId());
                location.add(temp);
            }
        }
        Collections.reverse(location);
        map.put("statistics", statistics);
        map.put("folders", folders);
        map.put("files", files);
        map.put("nowFolder", nowFolder);
        map.put("location", location);
        logger.info("网盘页面域中的数据:" + map);
        return "u-admin/file-store";
    }

    /**
     * @return java.lang.String
     * @Description 前往消息页面
     * @Author xw
     * @Date 12:57 2020/2/23
     * @Param [map]
     **/
    @RequestMapping("/messages")
    public String toMessagePage(String cur, Map<String, Object> map) {
        cur = cur == null ? "new" : cur;
        List<Message> newMessage = messageService.getAllMessageWithCondition(loginUser.getUserId(), false);
        List<Message> allMessage = messageService.getAllMessage(loginUser.getUserId());
        List<MessageToShow> newMessageToShows = transformMessage(newMessage, loginUser);
        List<MessageToShow> allMessageToShows = transformMessage(allMessage, loginUser);
        map.put("newMessages", newMessageToShows);
        map.put("allMessages", allMessageToShows);
        map.put("newMessageCount", newMessage.size());
        map.put("cur", cur);
        return "u-admin/messages";
    }

    /**
     * 跳转到主页，从数据库中获取5篇文章进行显示
     *
     * @param currentPage 当前获取文章的页数
     * @return java.lang.String
     * @author GGBOY
     * @date 2020/2/9
     */
    @ResponseBody
    @PostMapping("/index/articles/{currentPage}")
    public String toIndex(@PathVariable Integer currentPage) {
        logger.info("获取文章并显示。。。。。" + currentPage);
        if (currentPage == 1) {
            List<ArticleToShow> articleToShows = ApplicationStartListener.getArticleToShowList();
            return JSONObject.toJSONString(articleToShows, SerializerFeature.DisableCircularReferenceDetect,
                    SerializerFeature.WriteMapNullValue);
        } else {
            // 定义存储显示实体类的容器
            List<ArticleToShow> articleToShows = new ArrayList<>(10);
            // 定义初次刷新显示的文章数 5篇状态，5篇博客
            Integer pageSize = 5;
            // 获得总的文章数
            Integer allArticlesNumber = articleService.getArticlesNumber();
            logger.info("文章总数：" + allArticlesNumber);
            if (currentPage * pageSize * 2 > allArticlesNumber && (currentPage - 1) * pageSize * 2 < allArticlesNumber) {
                // 如果当前获取的文章数已超过了总的文章数，则显示剩下的文章
                pageSize = allArticlesNumber - ((currentPage - 1) * pageSize);
            } else if (currentPage * pageSize * 2 > allArticlesNumber && (currentPage - 1) * pageSize * 2 > allArticlesNumber) {
                // 全部文章都显示了，提示没有更多内容了！
                return "ERROR";
            }

            // 分页获取数据
            PageHelper.startPage(currentPage, pageSize);
            // 先选取5篇文章进行显示
            List<Article> articles = articleService.getNewestFiveArticle();
            // 分页获取数据
            PageHelper.startPage(currentPage, pageSize);
            // 获取5篇状态
            List<Article> postArticles = articleService.getNewestFivePost();
            // 封装文章信息
            traversalArticleList(articleToShows, articles);
            // 封装状态信息
            traversalArticleList(articleToShows, postArticles);
            return JSONObject.toJSONString(articleToShows, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
        }
    }

    @RequestMapping("/load/more")
    public String loadMoreContent(Integer currentPage, String userName, Model model) {
        logger.info("加载第几页文章：" + currentPage);
        User user = userService.getUserByUserName(userName);
        // 定义存储显示实体类的容器
        List<ArticleToShow> articleToShows = new ArrayList<>(10);
        // 定义初次刷新显示的文章数 5篇状态，5篇博客
        Integer pageSize = 5;
        // 获得总的文章数
        Integer allArticlesNumber = articleService.getArticlesNumber();
        logger.info("文章总数：" + allArticlesNumber);
        if (currentPage * pageSize > allArticlesNumber && (currentPage - 1) * pageSize < allArticlesNumber) {
            // 如果当前获取的文章数已超过了总的文章数，则显示剩下的文章
            pageSize = allArticlesNumber - ((currentPage - 1) * pageSize);
        } else if (currentPage * pageSize > allArticlesNumber && (currentPage - 1) * pageSize > allArticlesNumber) {
            // 全部文章都显示了，提示没有更多内容了！
            return "ERROR";
        }
        // 分页获取数据
        PageHelper.startPage(currentPage, pageSize);
        List<Article> articles = articleService.getAllArticlesByUserId(user.getUserId());
        // 封装信息
        traversalArticleList(articleToShows, articles);
        List<List<String>> images = new ArrayList<>();
        for (Article article : articles) {
            if (article.getImgPath() != null) {
                List<String> strings = new ArrayList<>();
                JSONArray jsonArray = JSONArray.parseArray(article.getImgPath());
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                    String path = (String) jsonObject.get("path");
                    strings.add(path);
                }
                images.add(strings);
            } else {
                images.add(null);
            }
        }
        model.addAttribute("visitUser", user);
        model.addAttribute("articles", articleToShows);
        model.addAttribute("images", images);
        return "commonContent::addArticle";
    }

    /**
     * 遍历文章列表，封装对应信息（如评论）到文章显示类实体中
     *
     * @param articleToShows 文章显示实体类列表
     * @param articles       文章列表
     * @author GGBOY
     * @date 2020/2/28
     */
    public void traversalArticleList(List<ArticleToShow> articleToShows, List<Article> articles) {
        for (Article article : articles) {
            // 获取文章的所有评论
            List<ArticleCommentToShow> commentsByArticleId = articleCommentService.getCommentsByArticleId(article.getArticleId());
            logger.info("长度：" + commentsByArticleId.size());
            // 获取评论中的所有一级评论
            List<ArticleCommentToShow> fatherComments = extractFatherComment(commentsByArticleId);
            logger.info("一级评论大小：" + fatherComments.size());
            // 将所有二级评论添加到对应的一级评论中
            extractChildCommentToFatherComment(commentsByArticleId, fatherComments);
            logger.info(fatherComments.toString());
            // 获取对文章点过赞的用户
            List<User> users = articleLikeService.findLikeUsersByArticleId(article.getArticleId());
            ArticleToShow articleToShow = ArticleToShow.builder()
                    .author(userService.getUserById(article.getUserId())).article(article)
                    .likeCount(articleService.getLikeCountByArticle(article.getArticleId()))
                    .commentCount(articleService.getCommentCountByArticle(article.getArticleId())).build();
            articleToShow.setLikeUserList(users);
            articleToShow.setArticleComments(fatherComments);
            articleToShows.add(articleToShow);
        }
    }

    /**
     * 从评论集合中提取一级评论
     *
     * @param commentToShows 评论集合
     * @return java.util.List<com.molihub.entity.ArticleCommentToShow>
     * @author GGBOY
     * @date 2020/2/15
     */
    public List<ArticleCommentToShow> extractFatherComment(List<ArticleCommentToShow> commentToShows) {
        List<ArticleCommentToShow> fatherComments = new ArrayList<>();
        Iterator<ArticleCommentToShow> iterator = commentToShows.iterator();
        while (iterator.hasNext()) {
            // 遍历评论集合，提取一级评论
            ArticleCommentToShow comment = iterator.next();
            logger.info("评论ID:" + comment.getArticleComment().getArticleCommentId());
            if (comment.getArticleComment().getToId() == null) {
                // toId为空表示是一级评论
                fatherComments.add(comment);
                // 将该一级评论从评论集合汇总删除
                iterator.remove();
            }
        }
        logger.info("fatherComments大小：" + fatherComments.size());
        return fatherComments;
    }

    /**
     * 将二级评论添加到对应的一级评论中
     *
     * @param commentToShows 二级评论集合
     * @param fatherComments 一级评论
     * @author GGBOY
     * @date 2020/2/15
     */
    public void extractChildCommentToFatherComment(List<ArticleCommentToShow> commentToShows, List<ArticleCommentToShow> fatherComments) {
        logger.info("二级评论集合大小：" + commentToShows.size() + " 一级评论集合大小：" + fatherComments.size());
        // 遍历父评论集合
        for (ArticleCommentToShow fatherComment : fatherComments) {
            logger.info("一级评论ID: " + fatherComment.getArticleComment().getArticleCommentId());
            // 遍历子评论集合
            for (ArticleCommentToShow childComment : commentToShows) {
                logger.info("二级评论TOID: " + childComment.getArticleComment().getToId());
                if (childComment.getArticleComment().getToId().equals(fatherComment.getArticleComment().getArticleCommentId())) {
                    // 如果同一级评论中，二级评论回复的不是父评论，那么将其回复的用户名封账进评论
                    if(!childComment.getArticleComment().getToUserId().equals(fatherComment.getArticleComment().getUserId())){
                        User user = userService.getUserById(childComment.getArticleComment().getToUserId());
                        childComment.setToUserName(user.getUserName());
                    }
                    // 如果此子评论的to_id为父评论的id，则将该评论添加到父评论的子评论集合中
                    fatherComment.getChildComments().add(childComment);
                    logger.info("一级评论下的二级评论集合大小：" + fatherComment.getChildComments().size());
                }
            }
        }
    }


    /**
     * 查看他人的主页
     *
     * @param userName 用户名
     * @return java.lang.String
     * @author GGBOY
     * @date 2020/2/10
     */
    @GetMapping("/lookUserProfilePage")
    public String lookOtherProfilePage(String userName, Map<String, Object> map) {
        if (userName.equals(loginUser.getUserName())) {
            // 如果自己在主页点击了自己
            return "redirect:/ProfilePage";
        }
        // 获得被访问的用户
        User user = userService.getUserByUserName(userName);
        int userId = user.getUserId();
        //增加访问量
        String ip = getIpAddress(request);
        Visitor visitor = AddressUtils.getVisitor(ip);
        if (visitor != null) {
            visitor.setType(0);
            visitor.setVisitorId(loginUser.getUserId());
            visitor.setUserId(user.getUserId());
            visitorService.insert(visitor);
        }
        //获得5篇阅读量最高文章
        PageHelper.startPage(0, 5);
        List<Article> famousArticles = articleService.getFamousArticles(user.getUserId());
        //获得自己的分类目录和对应的文章数量
        List<ArticleKind> kindsByUserId = articleKindService.getArticleKindsByUserId(user.getUserId());
        List<ArticleKindToShow> kindToShows = transformKind(kindsByUserId, user);
        //获得自己的标签和对应的文章数量
        List<ArticleTag> tagsByUserId = articleTagService.getArticleTagsByUserId(user.getUserId());
        List<ArticleTagToShow> tagToShows = transformTag(tagsByUserId, user);
        //获得文章的日期归档信息
        List<ArticleDateArchive> archives = articleService.getArchive(user.getUserId());
        HomePage myHomePage = homePageService.findPageById(user.getUserId());
        logger.info("lookOtherProfilePage..." + userId);
        HomePage page = homePageService.findPageById(userId);
        OtherProfilePage otherProfilePage = new OtherProfilePage();
        otherProfilePage.setHomePage(page);
        otherProfilePage.setUser(user);
        session.setAttribute("otherHomePage", otherProfilePage);
        map.put("visitUser", user);
        // 查找对应被访问用户的文章
        PageHelper.startPage(0, 5);
        List<Article> articles = articleService.getAllArticlesByUserId(userId);
        List<ArticleToShow> articleToShows = new ArrayList<>(10);
        // 封装文章信息
        traversalArticleList(articleToShows, articles);
        List<List<String>> images = new ArrayList<>();
        for (Article article : articles) {
            if (article.getImgPath() != null) {
                List<String> strings = new ArrayList<>();
                JSONArray jsonArray = JSONArray.parseArray(article.getImgPath());
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                    String path = (String) jsonObject.get("path");
                    strings.add(path);
                }
                images.add(strings);
            } else {
                images.add(null);
            }
        }
        // 遍历每篇文章，看看我是否点过赞
        List<Boolean> booleanList = new ArrayList<>();
        for (ArticleToShow articleToShow : articleToShows) {
            int i;
            for(i = 0; i < articleToShow.getLikeUserList().size(); i++){
                if(articleToShow.getLikeUserList().get(i).getUserName().equals(loginUser.getUserName())){
                    booleanList.add(true);
                    break;
                }
            }
            if(i == articleToShow.getLikeUserList().size()){
                booleanList.add(false);
            }
        }
        map.put("whetherLike", booleanList);
        map.put("articles", articleToShows);
        map.put("images", images);
        map.put("articles", articleToShows);
        map.put("famousArticles", famousArticles);
        map.put("archives", archives);
        map.put("kindToShows", kindToShows);
        map.put("tagToShows", tagToShows);
        logger.info("lookProfilePage: articles size: " + articleToShows.size());
        return "otherProfilePage";
    }

    /**
     * @return java.util.List<com.molihub.entity.Article>
     * @Description 获得文章的每个标签相关的所有文章获得最后的总集合
     * @Author xw
     * @Date 12:15 2020/2/15
     * @Param [tags, function]
     **/
    private List<Article> getArticlesByTags(String[] tags, Function<String, List<Article>> function) {
        List<Article> result = new ArrayList<>();
        for (int i = 0; i < tags.length; i++) {
            List<Article> articles = function.apply(tags[i]);
            result.addAll(articles);
        }
        return result;
    }

    /**
     * @return java.util.List<com.molihub.entity.ArticleToShow>
     * @Description 将Article集合转为ArticleToShow集合
     * @Author xw
     * @Date 15:38 2020/2/15
     * @Param [list, user]
     **/
    private List<ArticleToShow> transformArticle(List<Article> list, User user) {
        List<ArticleToShow> result = new ArrayList<>();
        for (Article article : list) {
            ArticleToShow temp = ArticleToShow.builder()
                    .article(article).author(user)
                    .likeCount(articleService.getLikeCountByArticle(article.getArticleId()))
                    .commentCount(articleService.getCommentCountByArticle(article.getArticleId())).build();
            result.add(temp);
        }
        return result;
    }

    /**
     * @return java.util.List<com.molihub.entity.ArticleKindToShow>
     * @Description 转换文章分类目录
     * @Author xw
     * @Date 15:12 2020/3/1
     * @Param [list, user]
     **/
    private List<ArticleKindToShow> transformKind(List<ArticleKind> list, User user) {
        List<ArticleKindToShow> result = new ArrayList<>();
        for (ArticleKind kind : list) {
            ArticleKindToShow temp = ArticleKindToShow.builder().kind(kind)
                    .count(articleService.getArticleCountByUserIdAndKind(user.getUserId(), kind.getArticleKindName())).build();
            result.add(temp);
        }
        return result;
    }

    /**
     * @return java.util.List<com.molihub.entity.ArticleKindToShow>
     * @Description 转换文章标签
     * @Author xw
     * @Date 15:12 2020/3/1
     * @Param [list, user]
     **/
    private List<ArticleTagToShow> transformTag(List<ArticleTag> list, User user) {
        List<ArticleTagToShow> result = new ArrayList<>();
        for (ArticleTag tag : list) {
            ArticleTagToShow temp = ArticleTagToShow.builder().tag(tag)
                    .count(articleService.getArticleCountByUserIdAndTag(user.getUserId(), tag.getArticleTagName())).build();
            result.add(temp);
        }
        return result;
    }

    /**
     * @return java.util.List<com.molihub.entity.MessageToShow>
     * @Description 将 Message集合转换为MessageToShow集合
     * @Author xw
     * @Date 10:15 2020/2/23
     * @Param [list, user]
     **/
    private List<MessageToShow> transformMessage(List<Message> list, User user) {
        List<MessageToShow> result = new ArrayList<>();
        for (Message message : list) {
            MessageToShow temp = MessageToShow.builder()
                    .message(message).fromUser(userService.getUserById(message.getFromUserId())).build();
            if (message.getArticleId() != -1) {
                //获得文章
                Article article = articleService.getArticleById(message.getArticleId());
                if (article != null) {
                    if (article.getArticleTitle() != null) {
                        temp.setArticleTitle(article.getArticleTitle());
                    } else {
                        String content = article.getArticleContent();
                        temp.setArticleTitle(content.length() >= 20 ? content.substring(0, 20) : content);
                    }
                } else {
                    continue;
                }
            }
            if (message.getArticleCommentId() != -1) {
                temp.setCommentContent(articleCommentService.getArticleCommentContentByCommentId(message.getArticleCommentId()));
            }
            result.add(temp);
        }
        return result;
    }

    /**
     * @return java.lang.String
     * @Description 获取用户的真实IP
     * @Author xw
     * @Date 16:27 2020/2/16
     * @Param [request]
     **/
    public String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
